package com.project.quiktask.tests;

import com.project.quiktask.Task;
import com.project.quiktask.controller.AddHandler;
import com.project.quiktask.controller.TaskParser;
import com.project.quiktask.controller.UpdateHandler;
import com.project.quiktask.exception.StartDateAfterEndDateException;
import com.project.quiktask.exception.StartTimeAfterEndTimeException;
import com.project.quiktask.parser.Parser;
import com.project.quiktask.util.Result;
import com.project.quiktask.util.Variable;

import java.text.ParseException;
import java.util.Vector;

import static org.junit.Assert.*;

import org.junit.Test;

public class UpdateHandlerTEST {
	Vector<Task> expectedTasks = new Vector<Task>();
	Vector<Task> updatedTasks = new Vector<Task>();
	Vector<Task> originalTasks = new Vector<Task>();

	UpdateHandler update = new UpdateHandler();
	AddHandler add = new AddHandler();

	public void initialTasks() {
		addInitialTask("floating");
		addInitialTask("floating");
		addInitialTask("floating");
		addInitialTask("floating");
		addInitialTask("floating");

		addInitialTask("timed, 2pm 23/09 to 5pm 23/09");
		addInitialTask("timed, 2pm 23/09 to 5pm 23/09");
		addInitialTask("timed, 2pm 23/09 to 5pm 23/09");
		addInitialTask("timed, 2pm 23/09 to 5pm 23/09");
		addInitialTask("timed, 2pm 23/09 to 5pm 23/09");

		addInitialTask("deadline, by 4pm 27/09");
		addInitialTask("deadline, by 4pm 27/09");
		addInitialTask("deadline, by 4pm 27/09");
		addInitialTask("deadline, by 4pm 27/09");
		addInitialTask("deadline, by 4pm 27/09");

		addInitialTask("hybrid, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
		addInitialTask("hybrid, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
		addInitialTask("hybrid, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
		addInitialTask("hybrid, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
		addInitialTask("hybrid, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
	}

	public void testFloating()	{
		expectedTasks.clear();
		addExpectedTask("lunch with friends, 2pm 13/10 to 3pm 13/10");
		addExpectedTask("CS2103 Developer Guide, 6pm 12/10 to 8pm 12/10, by 12am 15/10");
		addExpectedTask("Buy groceries");
		addExpectedTask("Do CS2105 Assignment, by 8pm 16/10");
		addExpectedTask("Soccer Training, 6pm 11/10 to 9pm 11/10");
	}

	public void testTimed()	{
		expectedTasks.clear();
		addExpectedTask("lunch with friends, 2pm 13/10 to 3pm 13/10");
		addExpectedTask("CS2103 Developer Guide, 6pm 12/10 to 8pm 12/10, by 12am 15/10");
		addExpectedTask("Buy groceries, 2pm 23/09 to 5pm 23/09");
		addExpectedTask("Do CS2105 Assignment, 2pm 23/09 to 5pm 23/09, by 8pm 16/10");
		addExpectedTask("Soccer Training, 6pm 11/10 to 9pm 11/10");
	}

	public void testDeadline()	{
		expectedTasks.clear();
		addExpectedTask("lunch with friends, 2pm 13/10 to 3pm 13/10, by 4pm 27/09");
		addExpectedTask("CS2103 Developer Guide, 6pm 12/10 to 8pm 12/10, by 12am 15/10");
		addExpectedTask("Buy groceries, by 4pm 27/09");
		addExpectedTask("Do CS2105 Assignment, by 8pm 16/10");
		addExpectedTask("Soccer Training, 6pm 11/10 to 9pm 11/10, by 4pm 27/09");
	}

	public void testHybrid()	{
		expectedTasks.clear();
		addExpectedTask("lunch with friends, 2pm 13/10 to 3pm 13/10, by 4pm 27/09");
		addExpectedTask("CS2103 Developer Guide, 6pm 12/10 to 8pm 12/10, by 12am 15/10");
		addExpectedTask("Buy groceries, 2pm 23/09 to 5pm 23/09, by 4pm 27/09");
		addExpectedTask("Do CS2105 Assignment, 2pm 23/09 to 5pm 23/09, by 8pm 16/10");
		addExpectedTask("Soccer Training, 6pm 11/10 to 9pm 11/10, by 4pm 27/09");
	}

	@Test
	public void testUpdateTask() {
		initialTasks();
		testFloating();
		updateEachTask();

		assertExpression();
		initialiseList();
		testTimed();
		updateEachTask();

		assertExpression();
		initialiseList();
		testDeadline();
		updateEachTask();

		assertExpression();
		initialiseList();
		testHybrid();
		updateEachTask();

		assertExpression();
	}

	public void assertExpression() {
		for (int i = 0; i < expectedTasks.size(); i++) {
			assertEquals("test", expectedTasks.get(i).toString(), updatedTasks.get(i).toString());
		}
	}

	public void initialiseList()	{
		if (originalTasks.size() != 6) {
			originalTasks.subList(0, 5).clear();
		}
	}

	public void updateEachTask() {
		updatedTasks.clear();
			updateTask("lunch with friends, 2pm 13/10 to 3pm 13/10", 0);
			updateTask("CS2103 Developer Guide, 6pm 12/10 to 8pm 12/10, by 12am 15/10", 1);
			updateTask("Buy groceries", 2);
			updateTask("Do CS2105 Assignment, by 8pm 16/10", 3);
			updateTask("Soccer Training, 6pm 11/10 to 9pm 11/10", 4);

	}


/*	public void testTaskSearchFailure() {
		Vector<Task> noResults = new Vector<Task>();
		Vector<Task> duplicateResults = new Vector<Task>();

		duplicateResults.add(new Task());
		duplicateResults.add(new Task());

		Result resultNoMatch = new Result(Variable.FEEDBACK_NO_MATCHING_RESULTS);
		Result resultDuplicateMatch = new Result(Variable.FEEDBACK_MANY_TASKS_WITH_SAME_KEYWORD);

		//		assertEquals("Check for no matching results", resultNoMatch, TextBuddy.searchForWord(search));
		//		assertEquals("Check whether it finds search term", test, TextBuddy.searchForWord(search));
	}*/

	public void addInitialTask(String parameter)	{
		String[] fields = Parser.parseString(parameter);
		try {
			Task newTask = TaskParser.getTaskFromString(fields);
			originalTasks.add(newTask);
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (StartDateAfterEndDateException e) {
			e.printStackTrace();
		} catch (StartTimeAfterEndTimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void addExpectedTask(String parameter)	{
		String[] fields = Parser.parseString(parameter);
		try {
			Task newTask = TaskParser.getTaskFromString(fields);
			expectedTasks.add(newTask);
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (StartDateAfterEndDateException e) {
			e.printStackTrace();
		} catch (StartTimeAfterEndTimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void updateTask(String parameter, int i)	{
		update.taskToBeUpdated = originalTasks.get(i);
		update.updateTask(null + ", " + parameter);
		updatedTasks.add(update.updatedTask);
	}

}
